import { Worker } from "worker_threads";
import path from "path";

export class KlMcClientProxy {
  private worker: Worker;
  constructor() {
    this.worker = new Worker(path.join(__dirname, "worker.js"));
  }

  private sendMessageToWorker(msg: any): Promise<any> {
    return new Promise((resolve, reject) => {
      const handler = (response: any) => {
        this.worker.off("message", handler);
        if (response.type === "error") {
          reject(new Error(response.error));
        } else {
          resolve(response);
        }
      };
      this.worker.on("message", handler);
      this.worker.postMessage(msg);
    });
  }

  async initClient(ipAddr: string, port: number) {
    try {
      await this.sendMessageToWorker({
        type: "init",
        ipAddr, // PLC IP
        port,
        options: { timeout: 5000 },
      });
      console.log("Client initialized in worker");
    } catch (error: any) {
      console.error("Init failed:", error.message);
    }
  }

  async close() {
    try {
      await this.sendMessageToWorker({
        type: "close",
      });
    } catch (error: any) {
      console.error("close failed:", error.message);
    }
  }

  // 写字符串
  async writeString(deviceName: string, str: string) {
    try {
      await this.sendMessageToWorker({
        type: "write_str",
        deviceName,
        str,
      });
    } catch (error: any) {
      console.error("Write failed:", error.message);
    }
  }

  // 读字符串
  async readString(deviceName: string, strLength: number) {
    try {
      const result = await this.sendMessageToWorker({
        type: "read_str",
        deviceName,
        strLength,
      });
      return result.data;
    } catch (error: any) {
      console.error("Read failed:", error.message);
    }
  }

  // 写数组
  async writeArr(deviceName: string, arr: number[]) {
    try {
      await this.sendMessageToWorker({
        type: "write_arr",
        deviceName,
        arr,
      });
    } catch (error: any) {
      console.error("Write failed:", error.message);
    }
  }

  // 读数组
  async readArr(deviceName: string, arrLength: number) {
    try {
      const result = await this.sendMessageToWorker({
        type: "read_arr",
        deviceName,
        arrLength,
      });
      return result.data;
    } catch (error: any) {
      console.error("Read failed:", error.message);
    }
  }

  // 写数字
  async writeNum(deviceName: string, num: number) {
    try {
      await this.sendMessageToWorker({
        type: "write_num",
        deviceName,
        num,
      });
    } catch (error: any) {
      console.error("Write failed:", error.message);
    }
  }

  // 读数字
  async readNum(deviceName: string) {
    try {
      const result = await this.sendMessageToWorker({
        type: "read_num",
        deviceName,
      });
      return result.data;
    } catch (error: any) {
      console.error("Read failed:", error.message);
    }
  }
}
